package com.qys.livesMall.event.listener;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qys.livesMall.anchor.mapper.AnchorRewardConfigMapper;
import com.qys.livesMall.anchor.model.entity.AnchorRewardConfig;
import com.qys.livesMall.anchor.model.entity.H2Anchor;
import com.qys.livesMall.anchor.service.H2AnchorService;
import com.qys.livesMall.app.user.event.UserFriendEvent;
import com.qys.livesMall.app.user.model.dto.sys.UserFriendEventDTO;
import com.qys.livesMall.finance.enums.AccountBusinessTypeEnum;
import com.qys.livesMall.finance.model.dto.FinancePayDTO;
import com.qys.livesMall.finance.service.FinanceBusinessService;
import com.qys.livesMall.finance.util.BusinessNoUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author yxh
 */
@Slf4j
@RequiredArgsConstructor
public class AnchorServiceListener {

    private final H2AnchorService anchorService;
    private final AnchorRewardConfigMapper anchorRewardConfigMapper;
    private final FinanceBusinessService financeBusinessService;
    private final Map<Long, Object> userLocks = new ConcurrentHashMap<>();

    @Async
    @Order
    @EventListener(UserFriendEvent.class)
    public void userFriend(UserFriendEvent event) {
        UserFriendEventDTO dto = (UserFriendEventDTO) event.getSource();
        Long friendId = dto.getFriendId();

        // 获取用户的锁对象，如果不存在则创建一个新的锁对象
        synchronized (userLocks.computeIfAbsent(friendId, k -> new Object())) {
            try {
                //更新主播表粉丝数量
                H2Anchor anchor = anchorService.getOne(Wrappers.<H2Anchor>lambdaQuery().eq(H2Anchor::getUserId, friendId).eq(H2Anchor::getIsDelete, 0));
                int newFans = 0;
                if (anchor != null) {
                    newFans = dto.isConcern() ? anchor.getFansNumber() + 1 : anchor.getFansNumber() - 1;
                    anchor.setFansNumber(newFans);
                    anchorService.updateById(anchor);
                }
                //匹配粉丝总量奖励
                AnchorRewardConfig anchorRewardConfig = anchorRewardConfigMapper.selectOne(Wrappers.<AnchorRewardConfig>lambdaQuery()
                        .eq(AnchorRewardConfig::getAwardType, 3)
                        .le(AnchorRewardConfig::getAwardCondition, newFans)
                        .orderByDesc(AnchorRewardConfig::getAwardCondition)
                        .last("limit 1")
                );
                if(anchorRewardConfig != null){
                    //判断是否领取过该阶段奖励
                    int rewarded = anchorRewardConfigMapper.rewardJudgment(anchorRewardConfig.getConId(), friendId, false);
                    if(rewarded > 0){
                        return;
                    }
                    FinancePayDTO payDTO = new FinancePayDTO();
                    payDTO.setUserId(friendId);
                    payDTO.setBusinessType(AccountBusinessTypeEnum.FOLLOWER_BONUS);
                    payDTO.setAmountIncurred(anchorRewardConfig.getAwardAmount());
                    payDTO.setBusinessNo(BusinessNoUtil.get(AccountBusinessTypeEnum.FOLLOWER_BONUS));
                    payDTO.setDescription("主播粉丝总量奖励");
                    financeBusinessService.pay(payDTO);
                    if (payDTO.getSuccess()) {
                        anchorService.keepRewardRecords(anchorRewardConfig.getConId(), friendId);
                        log.info("主播粉丝总量奖励成功, 奖励配置id:{}，userId:{}", anchorRewardConfig.getConId(), friendId);
                    } else {
                        log.info("主播粉丝总量奖励失败, 奖励配置id:{}，userId:{}，原因：{}", anchorRewardConfig.getConId(), friendId, payDTO.getMessage());
                    }
                }
            } finally {
                // 在同步代码块的末尾删除userId对应的key
                userLocks.remove(friendId);
            }
        }

    }

}
